package com.nzw.service.impl.wx;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.nzw.common.Constant;
import com.nzw.common.service.wx.WXPlatform;
import com.nzw.common.service.wx.aes.XMLParse;
import com.nzw.pojo.member.User;
import com.nzw.pojo.shop.Shop;
import com.nzw.pojo.wx.MassageTemplate;
import com.nzw.redis.impl.common.RedisTemplate;
import com.nzw.service.impl.common.BaseServiceImpl;
import com.nzw.service.member.MemberService;
import com.nzw.service.shop.ShopService;
import com.nzw.service.wx.WXService;
import com.nzw.utils.HttpUtils;
import com.nzw.utils.RandCodeUtil;
import com.nzw.utils.ServletUtil;
import com.nzw.utils.WXUtil;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.util.HtmlUtils;

import javax.servlet.http.HttpSession;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by yinwx on 2017/11/28.
 * 微信支付controller
 */
@Service
public class WXServiceImpl extends BaseServiceImpl implements WXService {
    @Autowired
    WXPlatform wxPlatform;
    @Autowired
    MemberService memberService;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    HttpSession session;
    @Autowired
    ShopService shopService;




    @Override
    public Map<String, String> getOpenIdByPlainAuto(String auto, Long shopId) {
        String url = "https://api.mch.weixin.qq.com/tools/authcodetoopenid";
        Map<String,String> params = new HashMap<>();
        params.put("appid",wxPlatform.getPublicAppid());
        params.put("mch_id",wxPlatform.getPayMchid());
        params.put("auth_code",auto);
        params.put("nonce_str",RandCodeUtil.randNumberCodeByCustom("5",20));
        params.put("sign",wxPlatform.createPaySign(params));
        String xml = XMLParse.generateElementAsXml(params, "xml");
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "text/xml");
        String entity = HttpUtils.getResultEntity(url, headers, xml, HttpUtils.POST);
        try {
            logger.info("支付result:" + new String(entity.getBytes("ISO-8859-1"), "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        Element resultRoot = XMLParse.getRootElement(entity);
        String returnCode = resultRoot.elementText("return_code");
        String resultCode = resultRoot.elementText("result_code");
        if(returnCode.equals("SUCCESS")){
            Map<String,String> result = new HashMap<>();
            if(resultCode.equals("SUCCESS")){
                result.put("openid",resultRoot.elementText("openid"));
                result.put("appid",resultRoot.elementText("appid"));
                result.put("mch_id",resultRoot.elementText("mch_id"));
                return result;
            }else {
                String errCode = resultRoot.elementText("err_code");
                if(errCode.equals("SYSTEMERROR")){
                    result.put("err","系统错误");
                }else if(errCode.equals("AUTHCODEEXPIRE")){
                    result.put("err","授权码过期 ");
                }else if(errCode.equals("AUTH_CODE_ERROR")){
                    result.put("err","授权码错误");
                }else if (errCode.equals("AUTH_CODE_INVALID")){
                    result.put("err","授权码检验错误");
                }
                return result;
            }
        }

        return null;
    }

    @Override
    public Map<String,String> getOpenIdByAutoCode(String autoCode,Long shopId) {

        String url = "https://api.mch.weixin.qq.com/tools/authcodetoopenid";
        Shop shop = shopService.getShopById(shopId);
        Map<String,String> params = new HashMap<>();
        params.put("appid",wxPlatform.getPublicAppid());
        //params.put("sub_appid",shop.getAddress());
        params.put("mch_id",wxPlatform.getPayMchid());
        params.put("sub_mch_id",shop.getMacid());
        params.put("auth_code",autoCode);
        params.put("nonce_str", RandCodeUtil.randNumberCodeByCustom("5",20));
        params.put("sign",wxPlatform.createPaySign(params));
        String xml = XMLParse.generateElementAsXml(params, "xml");
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "text/xml");
        String entity = HttpUtils.getResultEntity(url, headers, xml, HttpUtils.POST);
        try {
            logger.info("支付result:" + new String(entity.getBytes("ISO-8859-1"), "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        Element resultRoot = XMLParse.getRootElement(entity);
        String returnCode = resultRoot.elementText("return_code");
        String resultCode = resultRoot.elementText("result_code");
        System.out.println("result==========="+resultCode+"retuencode===="+returnCode);
        if(resultCode.equals("SUCCESS") && returnCode.equals("SUCCESS")){
            Map<String,String> result = new HashMap<>();
            System.out.println("123123123");

            result.put("openid",resultRoot.elementText("openid"));
            result.put("appid",resultRoot.elementText("appid"));
            result.put("mch_id",resultRoot.elementText("mch_id"));
            result.put("sub_mch_id",resultRoot.elementText("sub_mch_id"));
            result.put("sub_appid",resultRoot.elementText("sub_appid"));
            result.put("sub_openid",resultRoot.elementText("sub_openid"));

            return result;
        }

        return null;
    }

    @Override
    public String getAccessToken() {
        String accessToken = redisTemplate.get(Constant.ACCESSTOKEN +wxPlatform.getPublicAppid());//缓存取出
        if (accessToken != null) {
            System.out.println("redis中的access" + accessToken);
            return accessToken;
        }
        Map<String,Object> params = new HashMap<>();
        params.put("grant_type", "client_credential");
        params.put("appid", wxPlatform.getPublicAppid());
        params.put("secret", wxPlatform.getPublicSecret());
        String entity = HttpUtils.getResultEntity(ServletUtil.generateUrlFixByMap("https://api.weixin.qq.com/cgi-bin/token",params), null, null, HttpUtils.GET);
        JSONObject jsonObject = JSON.parseObject(entity);
        System.out.println("tokenjson"+jsonObject);
        if (!jsonObject.containsKey("access_token")) {
            logger.error("获取access_token错误：" + jsonObject.toJSONString());
            return null;
        }

        accessToken = jsonObject.getString("access_token");
        int seconds = jsonObject.getIntValue("expires_in");//有效期，秒为单位
        redisTemplate.setex(Constant.ACCESSTOKEN +wxPlatform.getPublicAppid(), seconds - 600, accessToken);//设置定时清除


        System.out.println("用户accessToken:"+accessToken);
        return accessToken;
    }
    
    /**
     * 通过appid 和 secrt 用https来获取 accessTokan
     * @return accessTokan
     */

    @Override
    public String getWebAccessToken(String code) {
        if (StringUtils.isEmpty(code))
            return null;
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token";
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("appid", wxPlatform.getPublicAppid()));
        nvps.add(new BasicNameValuePair("secret", wxPlatform.getPublicSecret()));
        nvps.add(new BasicNameValuePair("code", code));
        nvps.add(new BasicNameValuePair("grant_type", "authorization_code"));
        String entity = HttpUtils.getResultEntityByFormData(url, null, nvps, HttpUtils.POST);
        return entity;
    }


    //保存用户信息
    @Override
    public boolean saveWXUserInfo(String recommenderOpenId, String openId, String webAccessToken) {
        //根据openId判断用户是否存在
        User user = getEntityByOneProperty(User.class,"openid",openId);
        System.out.println("保存用户");
        if(user != null){
            System.out.println("用户存在");
            session.setAttribute("userId",user.getId());
            session.setAttribute("user",user);
            System.out.println(session.getAttribute("userId"));
            return  true;
        }

       String entity = getWXUserInfo(openId, webAccessToken);
       //保存用具信息
        Boolean result =memberService.registerMember(recommenderOpenId,entity);
        System.out.println("记录用户信息"+result);
       return result;
    }
    
    //通过openid和accessToken获取微信用户信息
    @Override
    public String getWXUserInfo(String openId, String webAccessToken) {
        Map<String,Object> param=new HashMap<>();
        param.put("access_token", webAccessToken);
        param.put("openid", openId);
        param.put("lang", "zh_CN");
        String entity = HttpUtils.getResultEntityByFormData(ServletUtil.generateUrlFixByMap("https://api.weixin.qq.com/sns/userinfo",param), null, null, HttpUtils.GET);
        try {
            return new String(entity.getBytes("ISO-8859-1"), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }

    }




    //获取用户是否关注公众号
    @Override
    public Boolean isConcern(String token,String openid){
        Integer subscribe =null;
        String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="+token+"&openid="+openid+"&lang=zh_CN";
        try {
            URL urlGet = new URL(url);
            HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
            http.setRequestMethod("GET"); // 必须是get方式请求
            http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
            http.setDoOutput(true);
            http.setDoInput(true);
            http.connect();
            InputStream is = http.getInputStream();
            int size = is.available();
            byte[] jsonBytes = new byte[size];
            is.read(jsonBytes);
            String message = new String(jsonBytes, "UTF-8");
            JSONObject demoJson = JSONObject.parseObject(message);
            System.out.println("JSON字符串："+demoJson);
            subscribe = demoJson.getIntValue("subscribe");

            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 1==subscribe?true:false;
    }




    //微信模板消息
    @Override
    public Boolean sendWXMessage(MassageTemplate temp) {

        boolean flag=false;
        String token = getAccessToken();
        String url="https://api.weixin.qq.com/cgi-bin/message/template/send";
        Map<String,Object> map = new HashMap<>();
        map.put("ACCESS_TOKEN", token);
        //讲模板消息转成json字符串
        String jsonString = JSON.toJSONString(temp);
        System.out.println("jsonString-----"+jsonString);
        url = ServletUtil.generateUrlFixByMap(url,map);
        //System.out.println("模板消息url:"+url);
        String entity= HttpUtils.getResultEntity(url, null, jsonString, HttpUtils.POST);
        JSONObject jsonResult = JSONObject.parseObject(entity);
        if(jsonResult!=null){
            int errorCode=jsonResult.getInteger("errcode");
            System.out.println(jsonResult);
            String errorMessage=jsonResult.getString("errmsg");
            if(errorCode==0){
                flag=true;
            }else{
                System.out.println("模板消息发送失败:"+errorCode+","+errorMessage);
                flag=false;
            }
        }
        return flag;

    }


    //获取所有微信用户openId
    @Override
    public List<String> getAllWXUserOpenId() {

        String token = getAccessToken();
        String url = "https://api.weixin.qq.com/cgi-bin/user/get";
        List<String> list = new ArrayList<>();
        Map<String,Object> map = new HashMap<>();
        map.put("ACCESS_TOKEN", token);
        url = ServletUtil.generateUrlFixByMap(url,map);
        String entity= HttpUtils.getResultEntity(url, null, null, HttpUtils.GET);
        JSONObject jsonResult = JSONObject.parseObject(entity);
        JSONObject data = jsonResult.getJSONObject("data");
        JSONArray array = data.getJSONArray("openid");
        for (int i = 0; i < array.size();i++){
            list.add(array.get(i).toString());
        }
        return list;
    }


    @Override
    public Map<String,String> getJsApi(String url,Boolean refersh){
        String ticket =getJsticket();
        return WXUtil.sign(ticket,url);
    }


    @Override
    public String getJsticket() {
        String token = getAccessToken();
        String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
        Map<String,Object> map = new HashMap<>();
        map.put("ACCESS_TOKEN", token);
        map.put("type","jsapi");
        url = ServletUtil.generateUrlFixByMap(url,map);
        String entity= HttpUtils.getResultEntity(url, null, null, HttpUtils.GET);
        JSONObject object = JSONObject.parseObject(entity);
        System.out.println("js签名返回数据:"+object);
        String ticket = object.getString("ticket");
        System.out.println("ticket:===="+ticket);
        redisTemplate.setex("redis_stick",7200,ticket);
        return ticket;
    }


}
